/*!
 *2018.07.04 wxd
 */
;
(function(factory) {
	'use strict';
	if(typeof define === 'function' && define.amd) {
		define(['jquery', 'leaflet', 'wicket.leaflet', "d3", "d3pie", "mustache", 'leaflet.ChineseTmsProviders', 'leaflet.WMTS',
			'leaflet.measure', 'leaflet.MousePosition', 'leaflet.groupedlayercontrol', 'leaflet.Zoominfo', 'leaflet.markercluster',
			"leaflet.custom"
		], factory);
	} else {
		if(typeof module === 'object' && module.exports) {
			//
		} else {
			factory(window.jQuery);
		}
	}
})(function($, L, Wkt, d3, d3pie, mustache) {
	var pluginName = "vw_map";

	var defaults = {
		height: $(window).height(),
		showMeasureControl: false,
		showZoominfo: true,
		showMousePosition: true,
		defaultMapview: {
			lat: 36,
			lon: 105,
			zoom: 4
		},
		minZoom: 1,
		maxZoom: 18,
		maxBounds: {
			xMin: -180,
			yMIn: -90,
			xMax: 180,
			yMax: 90,
		},
		defaultLayer: "image", //normal
		TWMSLayerURL: "",
		TileURL: "", //localStorage.getItem("ReadTile"),
		disableClusteringAtZoom: 19,
		pointSize: 10,
		svgColors: ["#44b9b0", "#e65414", "#d1c87f", "#7c37c0", "#cc9fb1", "#248838", "#ffff4c", "#ffeb4c", "#ffd84c", "#ffc44c"],
		pointbgColor: "#EE7600",
		textColor: "#FFFFFF",
		clusterColor: "#FF6347",
		gradientsColors: ["#ffff4c", "#ffeb4c", "#ffd84c", "#ffc44c", "#ffb04c", "#ff9d4c", "#ff894c", "#ff754c", "#ff624c"],
		icons: ["image/stz01.png", "image/stz02.png", "image/stz03.png", "image/stz04.png", "image/stz05.png"],
		onMouseoverMarker: null,
		onMouseoutMarker: null,
		onClickMarker: null
	};

	var methods = [
		'getMap',
		'getLayer',
		'getLayerByID',
		'getMarkers',
		'drawLabel',
		'drawPoint',
		'drawCluster',
		'drawPolygon',
		'drawIconMap',
		'drawSVGMap',
		'refresh',
		'resetMapview',
		'highlightMap',
		'cancelHighlightMap',
		'destroy'
	];

	var MAP_TOOL_TIP = '<p class="mapTooltip_title">{{title}}</p>' +
		'<ul class="mapTooltip_info">' +
		'	<li class="mapTooltip_divider"></li>' +
		'	{{#cols}}<li class="mapTooltip_prop">' +
		'		<span>{{title}}：</span>' +
		'		<span>{{info}}</span>' +
		'	</li>{{/cols}}' +
		'</ul>' +
		'<p class="mapTooltip_tag"></p>';

	var LEGEND = '<div class="legend_subject">' +
		'	{{#legends}}<div class="legend_line" style="height:{{lineHeight}};line-height:{{lineHeight}}">' +
		'		<div style="background:{{color}};border-radius:{{radius}};width:{{width}};height:{{height}};margin-top:{{marginTop}};margin-left:{{marginLeft}};"></div>' +
		'		<span>{{label}}</span>' +
		'	</div>{{/legends}}' +
		'</div>';

	var _map, _wkt, _layerControl, _layers, _curMarker, _leafletLegend;
	var _columns, _idIndex, _nameIndex, _themesIndexs, _enums;
	var that;

	var vw_map = function(element, options) {
		this.$element = $(element);
		this.options = $.extend({}, defaults, options);
		this._defaults = defaults;
		this._name = pluginName;
		this.version = 'v1.0.0';
		that = this;
		that._init();
	}

	vw_map.prototype = {
		_init: function() {
			that.$element.empty();

			//			var dlg = AddWMTS("http://www.scgis.net.cn/iMap/iMapServer/DefaultRest/services/newtianditudlg/WMTS", "聚合天地图瓦片地图服务");
			//			var dom = AddWMTS("http://www.scgis.net.cn/imap/imapserver/defaultrest/services/newtianditudom/WMTS", "四川省2017年DOM瓦片地图服务");
			//			var dlgdom = AddWMTS("http://www.scgis.net.cn/imap/imapserver/defaultrest/services/newtianditudom/WMTS", "四川省2017年DOM瓦片地图服务");

			var dlg = AddWMTS("http://10.151.10.200/iMap/iMapServer/defaultRest/services/scgis_dlg/WMTS", "SCGIS_DLG_NO");
			var dom = AddWMTS("http://10.151.10.200/imap/imapserver/defaultrest/services/scgis_dom/WMTS", "SCGIS_DOM_NO");
			var dlgdom = AddWMTS("http://10.151.10.200/imap/imapserver/defaultrest/services/scgis_domdlg/WMTS", "SCGIS_DOM-DLG_NO");

			var baseLayers = {
				"天地图矢量地图": dlg,
				"天地图影像地图": dom,
				"天地图路网地图": dlgdom
			};

			var defaultLayer;
			if(that.options.defaultLayer == "image") {
				defaultLayer = baseLayers["天地图影像地图"];
			} else {
				defaultLayer = baseLayers["天地图矢量地图"];
			}

			_map = L.map(that.$element[0].id, {
				zoomControl: false,
				attributionControl: false,
				minZoom: that.options.minZoom,
				maxZoom: that.options.maxZoom,
				maxBounds: L.latLngBounds(L.latLng(that.options.maxBounds.yMin, that.options.maxBounds.xMin), L.latLng(that.options.maxBounds.yMax, that.options.maxBounds.xMax)),
				layers: defaultLayer,
				crs: L.CRS.EPSG4326
			});

			_map.setView([that.options.defaultMapview.lat, that.options.defaultMapview.lon], that.options.defaultMapview.zoom);

			_layerControl = L.control.groupedLayers(baseLayers, {}, {
				groupCheckboxes: true
			});
			_map.addControl(_layerControl);

			if(that.options.TWMSLayerURL && that.options.TileURL) {
				AddCustomWMTSLayers();
			}

			if(that.options.showZoominfo) {
				new L.Control.Zoominfo({
					position: 'topleft', //bottomright
				}).addTo(_map);
			}

			if(that.options.showMousePosition) {
				L.control.mousePosition({
					position: 'bottomleft',
				}).addTo(_map);
			}

			if(that.options.showMeasureControl) {
				new L.Control.Measure({
					localization: 'cn',
					primaryLengthUnit: 'meters',
					secondaryLengthUnit: 'kilometers',
					primaryAreaUnit: 'sqmeters',
					secondaryAreaUnit: 'hectares',
					position: 'topright',
				}).addTo(_map);
			}

			_layers = [];
			_markers = [];
			_wkt = new Wkt.Wkt();
			_leafletLegend = "leafletCustomLegend";

			L.Marker.SVGMarker = L.Marker.extend({
				options: {
					"id": 0,
					"type": "",
					"code": 0,
					"data": {},
				},
				initialize: function(latlng, options) {
					options = L.Util.setOptions(this, options);
					this._latlng = latlng;
				},
				onAdd: function(map) {
					L.Marker.prototype.onAdd.call(this, map);
					if(this.options.type == "pie") {
						D3Pie('marker_svg_' + this.options.id, this.options.data);
					} else if(this.options.type == "bar") {
						SVGBar('marker_svg_' + this.options.id, this.options.data);
					} else {
						return;
					}
				}
			});

			that.resetMapview();
			window.onresize = that.resetMapview;
		},

		resetMapview: function() {
			that.$element.height(that.options.height);
			L.Util.requestAnimFrame(_map.invalidateSize, _map, false, _map._container);
		},

		refresh: function() {
			if(_layers) {
				for(var i = _layers.length - 1; i >= 0; i--) {
					if(_layers[i].name.split('_')[0] == "Custom") {
						_map.removeLayer(_layers[i].layer);
						_layers.splice(i, 1);
						$('#' + _leafletLegend).remove();
					}
				}
			}
		},

		getMap: function() {
			return _map;
		},

		getLayer: function(name) {
			if(_layers) {
				for(var i = 0; i < _layers.length; i++) {
					if(_layers[i].name == name) {
						return _layers[i].layer;
					}
				}
			}
			return null;
		},

		getLayerByID: function(id) {
			if(_layers) {
				return _layers[id].layer;
			}
			return null;
		},

		getMarkers: function() {
			return _markers;
		},

		drawLabel: function(data, zoomto) {
			if(!data) {
				return;
			}

			var _layerGroup = new L.layerGroup();

			_columns = data.head.columns;
			_idIndex = data.head.id;
			_nameIndex = data.head.name;
			_themesIndexs = data.head.themes;
			_enums = data.head.enums;

			var points = [];
			var flag = 0;
			$.each(data.body, function(k, val) {
				if(!val.latlon || val.latlon.length < 2 || val.latlon[0] == null || val.latlon[1] == null) {
					flag++;
					return true;
				}
				points.push(val.latlon);

				var pop = mustache.render(MAP_TOOL_TIP, PopupText(val.content));

				var marker = new L.Marker(L.latLng(val.latlon), {
					code: val.content[_idIndex], //用于Highlight时找对应
					icon: new L.DivIcon({
						html: '<div style="background:' + that.options.svgColors[val.content[_enums.key]] + ';color:' + that.options.textColor + ';"><span>' + val.content[_nameIndex] + '</span></div> ',
						className: "marker-addPoints point-icon",
						iconSize: new L.Point(30, 15),
					})
				}).bindTooltip(pop).addTo(_layerGroup);

				marker.on('mouseover', function(e) {
					if(that.options.onMouseoverMarker) {
						that.options.onMouseoverMarker.call(that, e.target.options.code);
					}
				}).on('mouseout', function(e) {
					if(that.options.onMouseoutMarker) {
						that.options.onMouseoutMarker.call(that, e.target.options.code);
					}
				}).on('click', function(e) {
					if(that.options.onClickMarker) {
						that.options.onClickMarker.call(that, e.target.options.code);
					}
				});

				_markers.push(marker);
			});

			if(points.length > 0) {
				_map.addLayer(_layerGroup);
				if(zoomto) {
					_map.fitBounds(L.latLngBounds(points));
				}

				_layers.push({
					name: "Custom_" + _layerGroup._leaflet_id,
					layer: _layerGroup
				});

				var legend = [];
				$.each(_enums.dic, function(k, val) {
					legend.push({
						color: that.options.svgColors[k],
						label: val
					});
				});

				RenderLegend(legend);
			}

			if(flag > 0) {
				$.Notify({
					caption: "提示",
					content: "该数据 " + data.body.length + " 条记录中 " + flag + " 条缺失位置信息！",
					type: "info"
				});
			};
		},

		drawPoint: function(data, zoomto, withLine) {
			if(!data) {
				return;
			}

			var _layerGroup = new L.layerGroup();

			_columns = data.head.columns;
			_idIndex = data.head.id;
			_nameIndex = data.head.name;
			_themesIndexs = data.head.themes;
			_enums = data.head.enums;

			var points = [];
			var flag = 0;
			$.each(data.body, function(k, val) {
				if(!val.latlon || val.latlon.length < 2 || val.latlon[0] == null || val.latlon[1] == null) {
					flag++;
					return true;
				}
				points.push(val.latlon);

				var pop = mustache.render(MAP_TOOL_TIP, PopupText(val.content));

				var marker = new L.Marker(L.latLng(val.latlon), {
					code: val.content[_idIndex], //用于Highlight时找对应
					icon: new L.DivIcon({
						html: '<div style="background:' + that.options.svgColors[val.content[_enums.key]] + ';color:' + that.options.textColor + ';"><span>' + val.content[_nameIndex] + '</span></div> ',
						className: "marker-addPoints point-icon",
						iconSize: new L.Point(15, 15),
					})
				}).bindTooltip(pop).addTo(_layerGroup);

				marker.on('mouseover', function(e) {
					if(that.options.onMouseoverMarker) {
						that.options.onMouseoverMarker.call(that, e.target.options.code);
					}
				}).on('mouseout', function(e) {
					if(that.options.onMouseoutMarker) {
						that.options.onMouseoutMarker.call(that, e.target.options.code);
					}
				}).on('click', function(e) {
					if(that.options.onClickMarker) {
						that.options.onClickMarker.call(that, e.target.options.code);
					}
				});

				_markers.push(marker);
			});

			if(points.length > 0) {
				if(withLine) {
					L.polyline(points, {
						color: 'red',
						dashArray: '5,5'
					}).addTo(_layerGroup);
				};
				_map.addLayer(_layerGroup);
				if(zoomto) {
					_map.fitBounds(L.latLngBounds(points));
				}

				_layers.push({
					name: "Custom_" + _layerGroup._leaflet_id,
					layer: _layerGroup
				});

				var legend = [];
				$.each(_enums.dic, function(k, val) {
					legend.push({
						color: that.options.svgColors[k],
						label: val
					});
				});

				RenderLegend(legend);
			}

			if(flag > 0) {
				$.Notify({
					caption: "提示",
					content: "该数据 " + data.body.length + " 条记录中 " + flag + " 条缺失位置信息！",
					type: "info"
				});
			};
		},

		drawCluster: function(data, zoomto, zoomlevel) {
			if(!data) {
				return;
			}

			_columns = data.head.columns;
			_idIndex = data.head.id;
			_nameIndex = data.head.name;
			_themesIndexs = data.head.themes;
			_enums = data.head.enums;

			var _layerGroup = new L.MarkerClusterGroup({
				spiderfyOnMaxZoom: true,
				showCoverageOnHover: false,
				singleMarkerMode: true,
				disableClusteringAtZoom: that.options.disableClusteringAtZoom,
				iconCreateFunction: function(e) {
					var count = e.getChildCount();
					var classtype = "marker-cluster";
					var size = {
						width: 40,
						height: 40
					};
					if(count < 2) {
						count = "";
						classtype = "marker-custom";
						size = {
							width: 20,
							height: 20
						}
					}
					return new L.divIcon({
						html: '<div style="background:' + that.options.clusterColor + '"><span>' + count + '</span></div>',
						className: classtype,
						iconSize: new L.Point(size.width, size.height)
					})
				}
			});

			var points = [];
			var flag = 0;
			$.each(data.body, function(k, val) {
				if(!val.latlon || val.latlon.length < 2 || val.latlon[0] == null || val.latlon[1] == null) {
					flag++;
					return true;
				}
				points.push(val.latlon);

				var pop = mustache.render(MAP_TOOL_TIP, PopupText(val.content));

				var marker = new L.Marker(L.latLng(val.latlon), {
					code: val.content[_idIndex] //用于Highlight时找对应
				}).bindTooltip(pop).addTo(_layerGroup);

				marker.on('mouseover', function(e) {
					if(that.options.onMouseoverMarker) {
						that.options.onMouseoverMarker.call(that, e.target.options.code);
					}
				}).on('mouseout', function(e) {
					if(that.options.onMouseoutMarker) {
						that.options.onMouseoutMarker.call(that, e.target.options.code);
					}
				}).on('click', function(e) {
					if(that.options.onClickMarker) {
						that.options.onClickMarker.call(that, e.target.options.code);
					}
				});

				_markers.push(marker);
			});

			if(points.length > 0) {
				_map.addLayer(_layerGroup);
				if(zoomto) {
					_map.fitBounds(_layerGroup.getBounds());
				};

				_layers.push({
					name: "Custom_" + _layerGroup._leaflet_id,
					layer: _layerGroup
				});

				var legend = {
					color: that.options.pointbgColor,
					label: "数量"
				};
				RenderLegend(legend);
			}

			if(flag > 0) {
				$.Notify({
					caption: "提示",
					content: "该数据 " + data.body.length + " 条记录中 " + flag + " 条缺失位置信息！",
					type: "info"
				});
			};
		},

		drawPolygon: function(data, zoomto, style) {
			if(!data) {
				return;
			}

			if(!style) {
				style = {
					color: "#3388ff",
					weight: 2
				};
			}

			var _layerGroup = new L.MarkerClusterGroup();

			_columns = data.head.columns;
			_idIndex = data.head.id;
			_nameIndex = data.head.name;
			_themesIndexs = data.head.themes;
			_enums = data.head.enums;

			$.each(data.body, function(k, val) {
				var pop = mustache.render(MAP_TOOL_TIP, PopupText(val.content));

				_wkt.read(val.wkt);
				var marker = _wkt.toObject()
				marker.setStyle({
					code: val.content[_idIndex], //用于Highlight时找对应
					color: style.color,
					weight: style.weight
				}).bindTooltip(pop).addTo(_layerGroup);

				marker.on('mouseover', function(e) {
					if(that.options.onMouseoverMarker) {
						that.options.onMouseoverMarker.call(that, e.target.options.code);
					}
				}).on('mouseout', function(e) {
					if(that.options.onMouseoutMarker) {
						that.options.onMouseoutMarker.call(that, e.target.options.code);
					}
				}).on('click', function(e) {
					if(that.options.onClickMarker) {
						that.options.onClickMarker.call(that, e.target.options.code);
					}
				});

				_markers.push(marker);
			});

			_map.addLayer(_layerGroup);
			if(zoomto) {
				try{
					_map.fitBounds(_layerGroup.getBounds());
				}
				catch(ex){
					console.log(ex);
				}
			}

			_layers.push({
				name: "Custom_" + _layerGroup._leaflet_id,
				layer: _layerGroup
			});
		},

		drawIconMap: function(data, zoomto) {
			if(!data) {
				return;
			}

			var _layerGroup = new L.layerGroup();

			_columns = data.head.columns;
			_idIndex = data.head.id;
			_nameIndex = data.head.name;
			_themesIndexs = data.head.themes;
			_enums = data.head.enums;

			var points = [];
			var flag = 0;
			$.each(data.body, function(k, val) {
				if(!val.latlon || val.latlon.length < 2 || val.latlon[0] == null || val.latlon[1] == null) {
					flag++;
					return true;
				}
				points.push(val.latlon);

				var pop = mustache.render(MAP_TOOL_TIP, PopupText(val.content));

				var marker = L.marker(L.latLng(val.latlon), {
					code: val.content[_idIndex], //用于Highlight时找对应
					type: val.content[_enums.key],
					icon: L.icon({
						iconUrl: that.options.icons[val.content[_enums.key] - 1],
						className: 'obj-icon',
						iconSize: [12, 12],
					})
				}).bindTooltip(pop).addTo(_layerGroup);

				marker.on('mouseover', function(e) {
					if(that.options.onMouseoverMarker) {
						that.options.onMouseoverMarker.call(that, e.target.options.code);
					}
				}).on('mouseout', function(e) {
					if(that.options.onMouseoutMarker) {
						that.options.onMouseoutMarker.call(that, e.target.options.code);
					}
				}).on('click', function(e) {
					if(that.options.onClickMarker) {
						that.options.onClickMarker.call(that, e.target.options.code);
					}
				});

				_markers.push(marker);
			});

			if(points.length > 0) {
				_map.addLayer(_layerGroup);

				if(zoomto) {
					_map.fitBounds(L.latLngBounds(points));
				};

				_layers.push({
					name: "Custom_" + _layerGroup._leaflet_id,
					layer: _layerGroup
				});
			}

			if(flag > 0) {
				$.Notify({
					caption: "提示",
					content: "该数据 " + data.body.length + " 条记录中 " + flag + " 条缺失位置信息！",
					type: "info"
				});
			};
		},

		drawSVGMap: function(data, zoomto, type) {
			if(!data) {
				return;
			}

			var _layerGroup = new L.layerGroup();

			_columns = data.head.columns;
			_idIndex = data.head.id;
			_nameIndex = data.head.name;
			_themesIndexs = data.head.themes;
			_enums = data.head.enums;

			var points = [];
			var flag = 0;
			$.each(data.body, function(k, val) {
				if(!val.latlon || val.latlon.length < 2 || val.latlon[0] == null || val.latlon[1] == null) {
					flag++;
					return true;
				}
				points.push(val.latlon);

				var pop = mustache.render(MAP_TOOL_TIP, PopupText(val.content));

				var svgdata = [];
				for(var i in _themesIndexs) {
					svgdata.push({
						"id": val.content[_idIndex],
						"value": parseFloat(val.content[_themesIndexs[i]]),
						"label": _columns[_themesIndexs[i]].title,
						"color": that.options.svgColors[i],
					})
				};
				var marker = new L.Marker.SVGMarker(L.latLng(val.latlon), {
					id: k, //d3pie需要
					type: type,
					code: val.content[_idIndex], //用于Highlight时找对应
					data: svgdata,
					icon: L.divIcon({
						className: 'svg-icon',
						html: '<div id="marker_svg_' + k + '" ></div>' //svg需要
					})
				}).bindTooltip(pop).addTo(_layerGroup);

				marker.on('mouseover', function(e) {
					if(that.options.onMouseoverMarker) {
						that.options.onMouseoverMarker.call(that, e.target.options.code);
					}
				}).on('mouseout', function(e) {
					if(that.options.onMouseoutMarker) {
						that.options.onMouseoutMarker.call(that, e.target.options.code);
					}
				}).on('click', function(e) {
					if(that.options.onClickMarker) {
						that.options.onClickMarker.call(that, e.target.options.code);
					}
				});

				_markers.push(marker);
			});

			if(points.length > 0) {
				_map.addLayer(_layerGroup);
				if(zoomto) {
					_map.fitBounds(L.latLngBounds(points));
				}
				_layers.push({
					name: "Custom_" + _layerGroup._leaflet_id,
					layer: _layerGroup
				});

				var legend = [];
				for(var i in _themesIndexs) {
					legend.push({
						"label": _columns[_themesIndexs[i]].title,
						"color": that.options.svgColors[i],
					})
				}
				RenderLegend(legend);
			}

			if(flag > 0) {
				$.Notify({
					caption: "提示",
					content: "该数据 " + data.body.length + " 条记录中 " + flag + " 条缺失位置信息！",
					type: "info"
				});
			};
		},

		highlightMap: function(index) {
			that.cancelHighlightMap();

			if(_layers) {
				for(var i = 0; i < _layers.length; i++) {
					var ls = _layers[i].layer.getLayers();
					for(var j = 0; j < ls.length; j++) {
						if(ls[j].options.code == index) {
							ls[j].openTooltip();
							_curMarker = ls[j];
							return false;
						}
					}
				}
			}
		},

		cancelHighlightMap: function() {
			if(_curMarker) {
				_curMarker.closeTooltip();
			}
		},

		destroy: function() {
			that.$element.empty();
		}
	}

	function AddWMTS(url, name) {
		var matrixIds = [];
		for(var i = 0; i < 22; ++i) {
			matrixIds[i] = {
				identifier: 1 + i,
				topLeftCorner: new L.LatLng(90, -180)
			};
		}

		return new L.TileLayer.WMTS(url, {
			tileSize: 256,
			layer: name,
			style: "default",
			tilematrixSet: "c",
			format: "tile",
			matrixIds: matrixIds
		});
	}

	function AddCustomWMTSLayers() {
		$.ajax({
			url: that.options.TWMSLayerURL,
			type: 'GET',
			async: false,
			dataType: 'json',
			success: function(e) {
				for(var i = 0; i < e.layers.length; i++) {
					var group = e.layers[i];
					if(group.layers) {
						for(var j = 0; j < group.layers.length; j++) {
							var layer = group.layers[i];
							if(layer.tilePath != "") {
								var wmts = new L.TileLayer.WMTS(that.options.ReadTile + layer.tilePath, {
									TILEMATRIXSET: "default028mms",
								});
								_layerControl.addOverlay(wmts, layer.name, group.name);
								_layers.push({
									name: "WMTS_" + layer.name,
									layer: wmts
								});
							}
						}
					} else {
						if(group.tilePath != "") {
							var wmts = new L.TileLayer.WMTS(that.options.ReadTile + group.tilePath, {
								TILEMATRIXSET: "default028mms",
							});
							_layerControl.addOverlay(wmts, group.name, "");
							_layers.push({
								name: "WMTS_" + group.name,
								layer: wmts
							});
						}
					}
				}
			}
		})
	}

	function D3Pie(div, data) {
		var size = 20;
		var option = {
			size: {
				canvasHeight: size * 2,
				canvasWidth: size * 2,
				pieInnerRadius: 0,
				pieOuterRadius: size - 3
			},
			labels: {
				outer: {
					format: "none"
				},
				inner: {
					format: "none"
				}
			},
			data: {
				sortOrder: "value-asc",
				content: data
			},
			effects: {
				load: {
					effect: "none"
				},
				pullOutSegmentOnClick: {
					effect: "none"
				}
			},
			tooltips: {
				enabled: false
			},
			opacity: 0.7
		};
		new d3pie(div, option);
	}

	function SVGBar(div, data) {
		var size = 20;
		var canvasHeight = size * 2;
		var canvasWidth = size;
		var dom = document.getElementById(div);
		var svg = d3.select(dom).append("svg").attr("width", canvasWidth).attr("height", canvasHeight);
		var padding = {
			left: 0,
			right: 0,
			top: 1,
			bottom: 1
		};

		var vals = [];
		for(var i in data) {
			vals.push(data[i].value)
		}
		var XRange = d3.scale.ordinal().domain(d3.range(vals.length)).rangeRoundBands([0, canvasWidth - padding.left - padding.right]);
		var maxval = d3.max(vals);
		var minval = d3.min(vals);
		if(minval > 0) {
			if(minval > (maxval - minval) / 2) {
				minval = minval - (maxval - minval) / 2
			} else {
				minval = 0
			}
		} else {
			minval = minval - (maxval - minval) / 2
		}
		var yRange = d3.scale.linear().domain([minval, maxval]).range([canvasHeight - padding.top - padding.bottom, 0]);
		svg.selectAll(".MyRect").data(data).enter().append("rect")
			.attr("class", "MyRect")
			.attr("transform", "translate(" + padding.left + "," + padding.top + ")")
			.attr("x", function(i, e) {
				return XRange(e)
			})
			.attr("width", XRange.rangeBand())
			.attr("y", function(e) {
				return yRange(e.value)
			})
			.attr("height", function(e) {
				return canvasHeight - padding.top - padding.bottom - yRange(e.value)
			})
			.attr("fill", function(i, e) {
				return i.color
			})
			.style("fill-opacity", 0.7);
	}

	function PopupText(data) {
		var properties = [];
		if(_themesIndexs) {
			$.each(_themesIndexs, function(k, val) {
				var item = {
					title: _columns[val].title,
					info: data[val]
				};
				properties.push(item);
			});
		}
		var retval = {
			title: data[_nameIndex],
			cols: properties
		};
		return retval;
	};

	function RenderLegend(data) {
		$('#' + _leafletLegend).remove();
		L.control.custom({
			id: _leafletLegend,
			position: 'bottomright',
			content: mustache.render(LEGEND, {
				legends: data
			}),
		}).addTo(_map);
	}

	$.fn[pluginName] = function(option) {
		var value;
		var args = Array.prototype.slice.call(arguments, 1);

		this.each(function() {
			var $this = $(this);
			var data = $this.data(pluginName);

			if(typeof option === 'string') {

				if($.inArray(option, methods) < 0) {
					throw new Error("该方法不存在: " + option);
				}

				if(!data) {
					return;
				}

				value = data[option].apply(data, args);

				if(option === 'destroy') {
					$this.removeData(pluginName);
				}
			}

			if(!data) {
				$this.data(pluginName, (data = new vw_map(this, option)));
			}
		});

		return typeof value === 'undefined' ? this : value;
	};
});